package test.progenies.ecg.asm31.variables;

import static org.junit.Assert.assertNotNull;

import org.junit.Before;
import org.objectweb.asm.Opcodes;

import com.progenies.ecg.generator.ClassGenerator;
import com.progenies.ecg.generator.ClassGeneratorFactory;
import com.progenies.ecg.model.ClassObject;
import com.progenies.ecg.model.ConstructorObject;
import com.progenies.ecg.model.FieldObject;
import com.progenies.ecg.model.MethodObject;
import com.progenies.ecg.model.codeparts.lines.LineFactory;

public abstract class BaseTestStaticVariables {

	protected ClassGenerator clsGenerator;
	private static int counter = 0;

	@Before
	public void setUp() throws Exception {
		clsGenerator=ClassGeneratorFactory.getClassGenerator();
		assertNotNull(clsGenerator);
	}

	protected ClassObject createClass() {
		counter++;
		int index=counter;
		LineFactory lineFactory=clsGenerator.lineFactory;
		String subpackage=this.getClass().getPackage().getName().substring(this.getClass().getPackage().getName().lastIndexOf('.')+1);
		ClassObject cls=clsGenerator.objectFactory.classes.createClass("test."+subpackage+".StaticVariableTestClass"+index);
		cls.setSuperClass(Object.class);
		
		//creates static final field
		FieldObject<Long> fld=clsGenerator.objectFactory.fields.createField("staticField", long.class);
		fld.setModifiers(new int[] {Opcodes.ACC_PROTECTED, Opcodes.ACC_STATIC, Opcodes.ACC_FINAL});
		fld.setValue(88l);
		cls.getFields().add(fld);
		
		//creates instance final field
		FieldObject<Long> fld2=clsGenerator.objectFactory.fields.createField("instanceField", long.class);
		fld2.setModifiers(new int[] {Opcodes.ACC_PROTECTED, Opcodes.ACC_FINAL});
		fld2.setValue(56l);
		cls.getFields().add(fld2);
		
		//override default constructor
		ConstructorObject consObject=clsGenerator.objectFactory.constructors.createConstructor();
		consObject.setCode(lineFactory.methods.invokeSuperConstructor());
		cls.getConstructors().add(consObject);
		
		
		//instance method
		MethodObject mth=clsGenerator.objectFactory.methods.createMethod("instanceMethod");
		mth.setReturnType(long.class);
		mth.setCode(clsGenerator.lineFactory.methods.returnStaticValue(5l));
		cls.getMethods().add(mth);
		
		//static method
		MethodObject mthSt=clsGenerator.objectFactory.methods.createMethod("staticMethod");
		mthSt.setReturnType(long.class);
		mthSt.setModifiers(new int[] {Opcodes.ACC_STATIC, Opcodes.ACC_PRIVATE});
		mthSt.setCode(clsGenerator.lineFactory.methods.returnStaticValue(9l));
		cls.getMethods().add(mthSt);
				
		return cls;
	}

}
